﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Web;
using System.IO;
using log4net;

namespace Entangle
{
    class ServerConnector
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(ServerConnector));

        string uri;

        public ServerConnector(string pServerURI)
        {
            uri = pServerURI;
            if (!uri.EndsWith("/"))
                uri += @"/";
            if (!uri.StartsWith("http://"))
                uri = @"http://" + uri;

        }

        private readonly string URI_Synch = "Synch.php";
        private readonly string URI_Request = "Request.php";
        private readonly string URI_Check = "Check.php";
        private readonly string URI_Get = "Get.php";

        private readonly string PARAM_Synch = "synchKey={0}&publicKey={1}";
        private readonly string PARAM_Request = "xml={0}&userId={1}";
        private readonly string PARAM_Check = "userId={0}&timestamp={1}";
        private readonly string PARAM_Get = "userId={0}&rid={1}";

        private string Call(string pUri, string pData)
        {
            byte[] postBytes = Encoding.ASCII.GetBytes(pData);

            WebRequest webRequest = WebRequest.Create(uri+pUri);
            if (Properties.Settings.Default.UseProxy)
            {
                webRequest.Proxy = WebRequest.DefaultWebProxy;
                webRequest.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
            }
            webRequest.Method = WebRequestMethods.Http.Post;
            webRequest.ContentType = "application/x-www-form-urlencoded";

            Stream os = null;
            try
            {
                webRequest.ContentLength = postBytes.Length;
                os = webRequest.GetRequestStream();
                os.Write(postBytes, 0, postBytes.Length);
            }
            catch (WebException ex)
            {
                log.Error("Exception while making POST request:" + webRequest.ToString(), ex);
                return null;
            }
            finally
            {
                if (os != null)
                    os.Close();
            }

            // --- Response --- 
            string response;
            try
            {
                WebResponse webResponse = webRequest.GetResponse();
                if (webResponse == null)
                    throw new WebException("Did not get response from server.");

                StreamReader sr = new StreamReader(webResponse.GetResponseStream());
                response = sr.ReadToEnd().Trim();
            }
            catch (WebException ex)
            {
                log.Error("Exception while getting response from server", ex);
                return null;
            }
            if (response.Length == 0)
            {
                log.Error("Did not get response string!");
                return null;
            }
            return response;
        }


        public string Synch(string synchKey, string publicKey)
        {
            if (synchKey == null || synchKey == String.Empty)
                throw new ArgumentNullException("synchKey");
            if (publicKey == null || publicKey == String.Empty)
                throw new ArgumentNullException("publicKey");

            return Call(URI_Synch, String.Format(PARAM_Synch, synchKey, publicKey));
        }

        public string Request(string xml, int userId)
        {
            if (xml == null || xml == String.Empty)
                throw new ArgumentNullException("xml");
            
            return Call(URI_Request, String.Format(PARAM_Request, xml, userId.ToString()));
        }

        public string Check(int userId, DateTime timestamp)
        {
            if (timestamp == null)
                throw new ArgumentNullException("timestamp");

            return Call(URI_Check, String.Format(PARAM_Check, userId.ToString(), timestamp.ToString("yyyy-MM-dd hh:mm:ss")));
        }
        public string Get(int userId, int lastMsgId)
        {
            return Call(URI_Get, String.Format(PARAM_Get, userId.ToString(), lastMsgId));
        }
    }
}
